package com.ikingtech.framework.sdk.core.support;

import com.ikingtech.framework.sdk.utils.Tools;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

import java.lang.reflect.Method;
import java.util.Objects;

/**
 * @author tie yan
 */
@Slf4j
public class SpelParser {

    private SpelParser() {

    }

    private static final SpelExpressionParser EXPRESSION_PARSER = new SpelExpressionParser();

    private static final DefaultParameterNameDiscoverer PARAMETER_NAME_DISCOVERER = new DefaultParameterNameDiscoverer();

    private static final String RESPONSE_DATA_PREFIX = "_res";

    public static String parse(Method method, Object[] args, String expression, Object proceedResult) {
        if (Tools.Str.isNotBlank(expression)) {
            String[] params = PARAMETER_NAME_DISCOVERER.getParameterNames(method);
            if (null == params || params.length == 0) {
                return Tools.Str.EMPTY;
            }
            EvaluationContext context = new StandardEvaluationContext();
            for (int i = 0; i < params.length; i++) {
                context.setVariable(params[i], args[i]);
            }
            if (null == proceedResult && expression.contains(RESPONSE_DATA_PREFIX)) {
                return Tools.Str.EMPTY;
            }
            if (null != proceedResult) {
                // 方法执行结果不为空时才处理"_res"参数
                context.setVariable(RESPONSE_DATA_PREFIX, proceedResult);
            }
            try {
                return Objects.requireNonNull(EXPRESSION_PARSER.parseExpression(expression).getValue(context)).toString();
            } catch (Exception e) {
                log.error("parse expression fail[{}]", method.getName());
            }
        }
        return expression;
    }
}
